package org.medusa.packet.blob;

import java.io.IOException;
import java.io.OutputStream;

import org.medusa.buffer.Buffer;
import org.medusa.buffer.LineBuffer;

//1.分离数据包头，将packet变为抽象类
public abstract class BasePacket/* extends LineBuffer */{

	// packet head
	protected LineBuffer head;
	protected LineBuffer body;

	public BasePacket(int headlen, int bodylen) {
		// super(bodylen);
		this.head = new LineBuffer(headlen, 0);
		this.body = new LineBuffer(bodylen, bodylen);
	}

	public abstract void Trace(String pre);

	public abstract boolean Check();

	public abstract Error WriteHead(OutputStream output);

	public Error Write2IO(OutputStream output) {
		Error err = this.WriteHead(output);

		if (err == null) {
			try {
				if (this.body.DataSize() > 0)
					output.write(this.body.GetBytes(),
							this.body.GetReadOffset(),
							this.body.GetWriteOffset());
				output.flush();
			} catch (IOException e) {
				// e.printStackTrace();
				err = new Error(e.getMessage());
			}
		}
		return err;
	}

	// boolean
	public boolean ReadBoolean() {
		return this.body.ReadInt8() != 0;
	}

	public void WriteBoolean(boolean val) {
		this.body.WriteInt8(((byte) (val ? 1 : 0)));
	}

	// Byte
	public byte ReadByte() {
		return this.body.ReadInt8();
	}

	public void WriteByte(int val) {
		this.body.WriteInt8((byte) val);
	}

	// Int8
	public byte ReadInt8() {
		return this.body.ReadInt8();
	}

	public void WriteInt8(int val) {
		this.body.WriteInt8((byte) val);
	}

	// Int16
	public short ReadInt16() {
		return this.body.ReadInt16LE();
	}

	public void WriteInt16(int val) {
		this.body.WriteInt16LE(val);
	}

	// Int32
	public int ReadInt32() {
		return this.body.ReadInt32LE();
	}

	public void WriteInt32(int val) {
		this.body.WriteInt32LE(val);
	}

	// Int64
	public long ReadInt64() {
		return this.body.ReadInt64LE();
	}

	public void WriteInt64(long val) {
		this.body.WriteInt64LE(val);
	}
	
	// Line
	public String ReadLine(byte sep) {
		return this.body.ReadLine(sep);
	}
	
	public void WriteLine(String val, byte sep) {
		this.body.WriteLine(val, sep);
	}
	
	// String
	public String ReadString() {
		return this.body.ReadString();
	}

	public void WriteString(String val) {
		this.body.WriteString(val);
	}

	// Bytes
	public byte[] GetBytes() {
		return this.body.GetBytes();
	}

	public void WriteBytes(String val) {
		this.body.WriteBlob(val);
	}

	public void ReadBytes(byte[] bytes, int size) {
		this.body.ReadBlob(bytes, size);
	}
	
	public void WriteBytes(byte[] bytes, int size) {
		this.body.WriteBlob(bytes, size);
	}
	
	public void ReadBytes(Buffer dst, int size) {
		this.body.ReadBuffer(dst, size);
	}

	public void WriteBytes(Buffer src, int size) {
		this.body.WriteBuffer(src, size);
	}

	// size
	public int BodySize() {
		return this.body.BufferSize();
	}

	public int BodyDataSize() {
		return this.body.DataSize();
	}

	public int BodyFreeSize() {
		return this.body.FreeSize();
	}

}
